package com.sikaryofficial.backend.utils;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * @author : qinjinyuan
 * @desc : TODO  请填写你的功能描述
 * @date : 2024/07/18 9:07
 */
public class Lottery {

    public static void main(String[] args) {
        List<Award> awards = new ArrayList<>();
        awards.add(new Award("2等奖", 3, 2));
        awards.add(new Award("3等奖", 1, 1));
        awards.add(new Award("5等奖", 18, 10));
        awards.add(new Award("6等奖", 2, 1));
        awards.add(new Award("1等奖", 16, 16));
        awards.add(new Award("7等奖", 24, 24));
        awards.add(new Award("4等奖", 22, 22));
        awards.add(new Award("8等奖", 4, 1));
        LotteryEngine engine = new LotteryEngine();
        for (int i = 0; i < 1000; i++) {
//            awards = awards.stream().sorted((o1, o2) -> new BigDecimal(o2.getWinRatio()).compareTo(new BigDecimal(o1.getWinRatio())))
//                    .collect(Collectors.toList());
            Award award = engine.draw1(awards);
            System.out.print("第" + (i + 1) + "次抽奖");
            if (award != null) {
                System.out.println( "结果：" + award.name);
            }else{
                System.out.println("结果：未中奖");
            }
        }
    }

    @Setter
    @Getter
    @ToString
    static class Award {
        private String name;
        private double winRatio;
        private int stock;

        public Award(String name, double winRatio, int stock) {
            this.name = name;
            this.winRatio = winRatio;
            this.stock = stock;
        }
    }

    static class LotteryEngine {
        private final Random random = new Random();

        public Award draw(List<Award> awards) {
            double totalWinRatio = awards.stream().mapToDouble(Award::getWinRatio).sum();
            System.out.println("当前总概率：" + totalWinRatio);
            double rand = random.nextDouble() * totalWinRatio;
            System.out.println("当前随机数：" + rand);
            double cumulativeRatio = 0;
            int count = 0;
            for (Award award : awards) {
                cumulativeRatio += award.winRatio;
                System.out.println("循环次数：" + count++);
                System.out.println("rand ：" + rand  + " , cumulativeRatio：" + cumulativeRatio);
                if (rand <= cumulativeRatio) {
                    if (award.stock == -1 || award.stock > 0) {
                        if (award.stock != -1) {
                            award.stock--;
                        }
                        System.out.println("当前抽奖记录：" + award);
                        return award;
                    }
                }
            }
            return null;
        }

        public Award draw1(List<Award> awards) {
            double totalWinRatio = awards.stream().mapToDouble(Award::getWinRatio).sum();
            System.out.println("当前总概率：" + totalWinRatio);

            // 生成随机数
            double rand = random.nextDouble() * totalWinRatio;
            System.out.println("当前随机数：" + rand);

            double cumulativeRatio = 0;
            int count = 0;

            // 循环遍历奖项列表
            for (Award award : awards) {
                cumulativeRatio += award.getWinRatio(); // 累加概率值
                System.out.println("循环次数：" + count++);
                System.out.println("rand ：" + rand + " , cumulativeRatio：" + cumulativeRatio);

                // 如果随机数小于等于累加的概率值，则返回该奖项
                if (rand <= cumulativeRatio && (award.getStock() == -1 || award.getStock() > 0)) {
                    if (award.getStock() != -1) {
                        award.setStock(award.getStock() - 1); // 减少库存
                    }
                    System.out.println("当前抽奖记录1：" + award);
                    return award;
                }
            }

            // 如果没有找到奖项（理论上不应该发生，因为总概率为100%），则返回第一个符合条件的奖项
            for (Award award : awards) {
                if (award.getStock() == -1 || award.getStock() > 0) {
                    if (award.getStock() != -1) {
                        award.setStock(award.getStock() - 1); // 减少库存
                    }
                    System.out.println("当前抽奖记录2：" + award);
                    return award;
                }
            }

            // 如果所有奖项都已无库存，返回null
            return null;
        }
    }
}
